package com.njupt.yanglonglong.report.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.njupt.yanglonglong.report.demo.common.Result;
import com.njupt.yanglonglong.report.demo.entity.DeviceApplied;
import com.njupt.yanglonglong.report.demo.entity.RUser;
import com.njupt.yanglonglong.report.demo.server.SocketServer;
import com.njupt.yanglonglong.report.demo.service.DeviceAppliedService;
import com.njupt.yanglonglong.report.demo.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;

/**
 * @className: SocketTest
 * @Description: TODO test
 * @author: lpl
 * @date: 2021/5/26 16:05
 */
@RestController
@CrossOrigin
@Slf4j
public class SocketController {

    @Autowired
    DeviceAppliedService deviceAppliedService;

    @Autowired
    private RedisUtil redisUtil;

    @RequestMapping("/testSocket")
    public String testSocket() {
        List<DeviceApplied> deviceApplieds = deviceAppliedService.list();
        SocketServer socketServer = SocketServer.getChatByDeviceId(deviceApplieds.get(0).getDeviceId());

        socketServer.SendFileBeg("C:\\Users\\李沛隆\\Desktop\\ledram.jbc");
//        socketServer.SendFileBeg("C:\\Users\\李沛隆\\Desktop\\led.jbc");
        while (socketServer.getMediaUrl() == null) {

        }
        return socketServer.getMediaUrl();
    }


    /**
     * 前端用户申请设备
     *
     * @param request 用户id
     * @return deviceapplied实体
     */
    @RequestMapping("/getDeviceId")
    public Result<JSONObject> getDeviceId(HttpServletRequest request) {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            res.put("msg", "用户权限校验失败，请先登录");
            return Result.error(res);
        }
        String stuId = user.getUserId();
        log.info("getDeviceId收到: user{}", user);

        //判断是否已经选择设备
        DeviceApplied device = deviceAppliedService.getIsApplied(user.getUserId());
        if (device != null) {
            log.info("用户{}已经申请了设备，设备id为{}", user, device.getDeviceId());
            res.put("msg", "您已经选择了设备");
            res.put("data", device);
            return Result.success(res);
        }
        //获得可选设备
        DeviceApplied deviceApplied = deviceAppliedService.getOptionalDivices();
        if (deviceApplied == null) {
            log.info("[getDeviceId学生获取设备失败]");
            res.put("msg", "目前没有可用设备，设备繁忙或出错");
            return Result.error(res);
        }

        //用户登录设备,若失败报错
        if (!deviceAppliedService.onlineUser(stuId, deviceApplied)) {
            log.info("[getMediaUrl户占用设备失败]");
            res.put("msg", "用户上线设备失败");
            return Result.error(res);
        }
        res.put("data", deviceApplied);

        return Result.success(res);
    }


    /**
     * 发送文件同时等待流url
     *
     * @param request  用户id
     * @param file     文件
     * @param deviceId 设备id
     * @return 流地址
     */
    @RequestMapping("/getMediaUrl")
    public Result<JSONObject> getMediaUrl(HttpServletRequest request, MultipartFile file, String deviceId) {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            res.put("msg", "用户权限校验失败，请先登录");
            return Result.error(res);
        }
        log.info("/getMediaUrl收到: user{}", user);

        String stuId = user.getUserId();
        DeviceApplied deviceApplied = deviceAppliedService.getById(deviceId);

        //设备id查不到
        if (deviceApplied == null) {
            log.info("[getMediaUrl数据库获取设备出错]");
            res.put("msg", "查询数据库出错，可以再申请设备试试");
            return Result.success(res);
        }

        SocketServer socketServer = SocketServer.getChatByDeviceId(deviceApplied.getDeviceId());
        long startTime = System.currentTimeMillis();
        //开始向硬件发送文件
        socketServer.SendFileBeg(file);
        //没有返回推流文件时无法进行
        while (socketServer.getMediaUrl() == null) {
            try {
                //每0.5s看是否返回了URL
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if ((System.currentTimeMillis() - startTime) / 1000 > 60) {
                deviceAppliedService.offlineUser(deviceApplied);
                res.put("msg", "上传文件烧录超时，自动下线登录设备");
                return Result.error(res);
            }
        }
        //设备下线
        deviceAppliedService.offlineUser(deviceApplied);
        res.put("mediaUrl", socketServer.getMediaUrl());
        res.put("msg", "烧录已经完成");
        return Result.success(res);
    }


    /**
     * 轮询查看烧录信息
     *
     * @param request 用户
     * @param hashMap 设备id
     * @return 烧录信息
     */
    @RequestMapping("/pollingInformation")
    public Result<JSONObject> pollingInformation(HttpServletRequest request, @RequestBody HashMap<String, String> hashMap) {
        JSONObject res = new JSONObject();
        String token = request.getHeader("Authorization");
        RUser user = redisUtil.getUser(token);
        if (user == null) {
            res.put("msg", "用户权限校验失败，请先登录");
            return Result.error(res);
        }
        log.info("/pollingInformation收到: user{} map{}", user, hashMap);
        String deviceId = hashMap.get("deviceId");
        SocketServer socketServer = SocketServer.getChatByDeviceId(deviceId);
        String flashMessage = socketServer.getFlashMessage().toString();
        res.put("data", flashMessage);
        return Result.success(res);
    }

}
